package com.chwn.harulib.util;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Myshikin on 2017/3/28.
 */

public class CustomToast {
    private static Handler                    mHandler       = new Handler();
    @SuppressLint({"NewApi"})
    private static BlockingQueue<CustomToast> mQueue         = new LinkedBlockingDeque();
    private static AtomicInteger              mAtomicInteger = new AtomicInteger(0);
    private WindowManager              mWindowManager;
    private long                       mDurationMillis;
    private View                       mView;
    private WindowManager.LayoutParams mParams;
    private Context                    mContext;
    private final        Runnable mShow     = new Runnable() {
        public void run() {
            CustomToast.this.handleShow();
        }
    };
    private final        Runnable mHide     = new Runnable() {
        public void run() {
            CustomToast.this.handleHide();
        }
    };
    private static final Runnable mActivite = new Runnable() {
        public void run() {
            CustomToast.activeQueue();
        }
    };

    public static CustomToast makeText(Context context, String text, long duration) {
        return (new CustomToast(context)).setText(text).setDuration(duration).setGravity(17, 0, 0);
    }

    public static CustomToast makeText(Context context, View view, long duration) {
        return (new CustomToast(context)).setView(view).setDuration(duration).setGravity(17, 0, 0);
    }

    public CustomToast(Context context) {
        this.mContext = context;
        this.mWindowManager = (WindowManager) this.mContext.getSystemService(Context.WINDOW_SERVICE);
        this.mParams = new WindowManager.LayoutParams();
        this.mParams.height = -2;
        this.mParams.width = -2;
        this.mParams.format = -3;
        this.mParams.windowAnimations = 16973828;
        this.mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
        this.mParams.setTitle("Toast");
        this.mParams.flags = 152;
        this.mParams.gravity = 17;
    }

    @TargetApi(17)
    public CustomToast setGravity(int gravity, int xOffset, int yOffset) {
        int finalGravity;
        if (Build.VERSION.SDK_INT >= 14) {
            Configuration config = this.mView.getContext().getResources().getConfiguration();
            finalGravity = Gravity.getAbsoluteGravity(gravity, config.getLayoutDirection());
        } else {
            finalGravity = gravity;
        }

        this.mParams.gravity = finalGravity;
        if ((finalGravity & 7) == 7) {
            this.mParams.horizontalWeight = 1.0F;
        }

        if ((finalGravity & 112) == 112) {
            this.mParams.verticalWeight = 1.0F;
        }

        this.mParams.y = yOffset;
        this.mParams.x = xOffset;
        return this;
    }

    public CustomToast setDuration(long durationMillis) {
        if (durationMillis < 0L) {
            this.mDurationMillis = 0L;
        }

        if (durationMillis == 0L) {
            this.mDurationMillis = 2000L;
        } else if (durationMillis == 1L) {
            this.mDurationMillis = 3500L;
        } else {
            this.mDurationMillis = durationMillis;
        }

        return this;
    }

    public CustomToast setView(View view) {
        this.mView = view;
        return this;
    }

    public CustomToast setMargin(float horizontalMargin, float verticalMargin) {
        this.mParams.horizontalMargin = horizontalMargin;
        this.mParams.verticalMargin = verticalMargin;
        return this;
    }

    public CustomToast setText(String text) {
        Toast toast = Toast.makeText(this.mContext, text, Toast.LENGTH_SHORT);
        toast.setText(text);
        return this;
    }

    public void show() {
        mQueue.offer(this);
        if (mAtomicInteger.get() == 0) {
            mAtomicInteger.incrementAndGet();
            mHandler.post(mActivite);
        }

    }

    public void cancel() {
        if (mAtomicInteger.get() != 0 || !mQueue.isEmpty()) {
            if (this.equals(mQueue.peek())) {
                mHandler.removeCallbacks(mActivite);
                mHandler.post(this.mHide);
                mHandler.post(mActivite);
            }

        }
    }

    private void handleShow() {
        if (this.mView != null) {
            if (this.mView.getParent() != null) {
                this.mWindowManager.removeView(this.mView);
            }

            this.mWindowManager.addView(this.mView, this.mParams);
        }

    }

    private void handleHide() {
        if (this.mView != null) {
            if (this.mView.getParent() != null) {
                this.mWindowManager.removeView(this.mView);
                mQueue.poll();
            }

            this.mView = null;
        }

    }

    private static void activeQueue() {
        CustomToast toast = (CustomToast) mQueue.peek();
        if (toast == null) {
            mAtomicInteger.decrementAndGet();
        } else {
            mHandler.post(toast.mShow);
            mHandler.postDelayed(toast.mHide, toast.mDurationMillis);
            mHandler.postDelayed(mActivite, toast.mDurationMillis);
        }

    }
}
